﻿using System;
using System.Collections.Generic;
using System.Linq;
using Citi.Import.Util;
using System.ComponentModel;
using Citi.ResourceConsolidation.Domain.Utils;

namespace Citi.ResourceConsolidation.Domain
{   

    public partial class EmployeeClass
    {
        public enum ClassDescription
        {
            [Description("Full Time Employees")]
            FullTimeEmployees,
            [Description("Part Time FTE")]
            PartTimeFTE,
            [Description("Overtime")]
            Overtime,
            [Description("Agency/Temp FTE")]
            AgencyTempFTE,
            [Description("Contractor FTE")]
            ContractorFTE,
            [Description("Consultants")]
            Consultants
        };

        private const string EmployeeClassColumn = "Employee Class";
        private const string EmployeeClassDescriptionColumn = "Class Description";
        
        public static readonly List<Definition<EmployeeClass>> Definitions = new List<Definition<EmployeeClass>>
            {
                new Definition<EmployeeClass> { ModelProperty = x => x.Code, MaxLength = 50, Required = true, ColumnName = EmployeeClassColumn, CustomConversionMethod = ValidateCode},
                new Definition<EmployeeClass> { ModelProperty = x => x.Description, MaxLength = 300, Required = true, ColumnName = EmployeeClassDescriptionColumn},
            };

        private static object ValidateCode(ref EmployeeClass model, string value, List<string> fields, ref string error, List<string> headers = null)
        {
            if (String.IsNullOrEmpty(value))
            {
                error = String.Format("The field {0} can not be null", EmployeeClassColumn);
                return Conversion.Validation.Failed;
            }

            var domain = CacheFacade.Get(new EmployeeClass().SelectAll<EmployeeClass>).FirstOrDefault(x => x.Code == value);

            if (domain != null)
            {
                model = domain;
                return Conversion.Validation.Validated;
            }

            return value;
        }

        public static void Save(List<EmployeeClass> employeeClasses)
        {
            employeeClasses = employeeClasses.Distinct(new EmployeeClassComparer()).Where(x => x != null && !String.IsNullOrEmpty(x.Description) && x.Id == 0).ToList();

            if (!employeeClasses.Any()) return;
            employeeClasses.First().Save(employeeClasses, 100);

            CacheFacade.Clear(typeof(EmployeeClass));
            Context.ClearContext();
        }
    }

    public class EmployeeClassComparer : IEqualityComparer<EmployeeClass>
    {
        public bool Equals(EmployeeClass x, EmployeeClass y)
        {
            if (ReferenceEquals(x, y)) return true;
            if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
                return false;

            return x.Description == y.Description && x.Id == y.Id && x.Code == y.Code;
        }

        public int GetHashCode(EmployeeClass item)
        {
            if (ReferenceEquals(item, null)) return 0;

            int hashDescription = item.Description == null ? 0 : item.Description.GetHashCode();
            int hashId = item.Description == null ? 0 : item.Id.GetHashCode();
            int hashCode = item.Code == null ? 0 : item.Code.GetHashCode();

            return hashDescription ^ hashId ^ hashCode;
        }
    }
}
